Conversation
WalkthroughThis pull request introduces a new Switch component to the design system by adding a Radix UI-based implementation, comprehensive MDX documentation with live examples, updating the atoms registry, adding the required radix-ui dependency, and exporting the component from the main API surface. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes 🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment |
b70d2ba to
320f822
Compare
🍈 Lychee Link Check Report3664 links: ❌ Errors
Full Statistics Table
|
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apps/eclipse/content/design-system/atoms/switch.mdx`:
- Around line 467-477: The doc's styling tokens/sizes for the Switch component
are out of sync with the implementation; inspect the Switch component
implementation (named Switch) and either update this MDX (switch.mdx) to match
the actual classes (e.g., replace bg-input/bg-primary/thumb tokens with the
current bg-background-neutral-* classes and the actual Tailwind size utilities
used for heights/widths and thumb sizes) or change the component to use the
documented design tokens (bg-input, bg-primary, bg-background,
bg-primary-foreground, ring-ring/50, rounded-full, and the exact pixel sizes for
sm/default); ensure the MDX lists the same token names and pixel dimensions as
the component's classnames and that the focus ring, border (transparent with
shadow), and size variants (sm/default) exactly match the implementation.
- Around line 12-24: The examples render an unlabeled Switch which is
inaccessible; update the BasicSwitch component and the live example to provide
an accessible label by either passing an aria-label prop to the Switch (e.g.,
aria-label="Enable feature") or pairing the Switch with an explicit label
element and id. Specifically modify the BasicSwitch function (export function
BasicSwitch) to render <Switch aria-label="..."> (or wrap Switch with a <label
htmlFor="..."> and give the Switch an id) and update the inline Live Example
<Switch /> inside the demo div the same way so both examples show accessible
usage.
In `@packages/eclipse/src/components/switch.tsx`:
- Around line 14-27: The small variant lacks size classes so
SwitchPrimitive.Root and SwitchPrimitive.Thumb render without dimensions; add
matching data-[size=sm] rules alongside the existing data-[size=default] ones:
on SwitchPrimitive.Root add data-[size=sm]:h-... and data-[size=sm]:w-... (and
any disabled/outline equivalents) and on SwitchPrimitive.Thumb add
data-[size=sm] sizing (width/height) and adjust the translate-x for
data-[state=checked] for the sm thumb to correctly move to the end; update the
cn calls where data-[size=default] appears to include the corresponding
data-[size=sm] tokens so the small variant gets proper root and thumb dimensions
and translations.
- Around line 1-4: Add the client directive and correct Radix import: this file
uses the Radix Switch primitive so add "use client" as the first line of
packages/eclipse/src/components/switch.tsx, and change the import from
"radix-ui" to the scoped package "@radix-ui/react-switch" (the existing import
alias SwitchPrimitive should be preserved), ensuring the Switch component and
any references to SwitchPrimitive continue to work with the updated import.
- Line 2: Replace the import of SwitchPrimitive from the aggregator "radix-ui"
with the scoped package "@radix-ui/react-switch" and add
"@radix-ui/react-switch" to package.json dependencies; specifically update the
import statement that currently reads like `import { Switch as SwitchPrimitive }
from "radix-ui";` to import from "@radix-ui/react-switch" and run your package
install so SwitchPrimitive resolves the same way as other components
(tooltip/dialog/checkbox) in the codebase.
ℹ️ Review info
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (6)
apps/eclipse/content/design-system/atoms/meta.jsonapps/eclipse/content/design-system/atoms/switch.mdxapps/eclipse/src/app/layout.tsxpackages/eclipse/package.jsonpackages/eclipse/src/components/index.tspackages/eclipse/src/components/switch.tsx
| ```tsx | ||
| import { Switch } from "@prisma-docs/eclipse"; | ||
|
|
||
| export function BasicSwitch() { | ||
| return <Switch />; | ||
| } | ||
| ``` | ||
|
|
||
| **Live Example:** | ||
|
|
||
| <div className="flex gap-4 my-4"> | ||
| <Switch /> | ||
| </div> |
There was a problem hiding this comment.
Add accessible labeling to the basic examples.
The basic example and live example render an unlabeled Switch, which is an a11y anti-pattern. Add aria-label (or pair with a label) so examples don’t teach unsafe usage.
✅ Suggested updates
export function BasicSwitch() {
- return <Switch />;
+ return <Switch aria-label="Enable feature" />;
}
@@
<div className="flex gap-4 my-4">
- <Switch />
+ <Switch aria-label="Enable feature" />
</div>🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apps/eclipse/content/design-system/atoms/switch.mdx` around lines 12 - 24,
The examples render an unlabeled Switch which is inaccessible; update the
BasicSwitch component and the live example to provide an accessible label by
either passing an aria-label prop to the Switch (e.g., aria-label="Enable
feature") or pairing the Switch with an explicit label element and id.
Specifically modify the BasicSwitch function (export function BasicSwitch) to
render <Switch aria-label="..."> (or wrap Switch with a <label htmlFor="...">
and give the Switch an id) and update the inline Live Example <Switch /> inside
the demo div the same way so both examples show accessible usage.
| The Switch component uses Eclipse design tokens: | ||
|
|
||
| - **Unchecked background**: `bg-input` | ||
| - **Checked background**: `bg-primary` | ||
| - **Thumb**: `bg-background` (unchecked), `bg-primary-foreground` (checked in dark mode) | ||
| - **Focus ring**: `ring-ring/50` with 3px width | ||
| - **Border**: Transparent with shadow | ||
| - **Sizes**: | ||
| - Small (`sm`): 14px height × 24px width, 12px thumb | ||
| - Default: ~18px height × 32px width, 16px thumb | ||
| - **Border radius**: Fully rounded (`rounded-full`) |
There was a problem hiding this comment.
Verify the styling tokens/sizes match the implementation.
The styling section mentions bg-input, bg-primary, and specific pixel sizes, but the component currently uses bg-background-neutral-* and different size utilities. Please align docs with the real classes/tokens to avoid confusion.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apps/eclipse/content/design-system/atoms/switch.mdx` around lines 467 - 477,
The doc's styling tokens/sizes for the Switch component are out of sync with the
implementation; inspect the Switch component implementation (named Switch) and
either update this MDX (switch.mdx) to match the actual classes (e.g., replace
bg-input/bg-primary/thumb tokens with the current bg-background-neutral-*
classes and the actual Tailwind size utilities used for heights/widths and thumb
sizes) or change the component to use the documented design tokens (bg-input,
bg-primary, bg-background, bg-primary-foreground, ring-ring/50, rounded-full,
and the exact pixel sizes for sm/default); ensure the MDX lists the same token
names and pixel dimensions as the component's classnames and that the focus
ring, border (transparent with shadow), and size variants (sm/default) exactly
match the implementation.
| import * as React from "react"; | ||
| import { Switch as SwitchPrimitive } from "radix-ui"; | ||
|
|
||
| import { cn } from "../lib/cn"; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# Search for "use client" directives in component files
rg -n '"use client"' packages/eclipse/src/components/ --type tsxRepository: prisma/web
Length of output: 81
🏁 Script executed:
# Check the structure of other components to understand the pattern
fd '\.tsx$' packages/eclipse/src/components/ | head -10Repository: prisma/web
Length of output: 492
🏁 Script executed:
# Examine one or two other component files to see if they use "use client"
ls -la packages/eclipse/src/components/ | head -20Repository: prisma/web
Length of output: 1201
🏁 Script executed:
# Search for "use client" directive in components directory without type restriction
rg '"use client"' packages/eclipse/src/components/Repository: prisma/web
Length of output: 1248
🏁 Script executed:
# Examine a few component files to see if they have "use client" directive
cat packages/eclipse/src/components/checkbox.tsxRepository: prisma/web
Length of output: 1771
🏁 Script executed:
# Check another Radix-based component
cat packages/eclipse/src/components/accordion.tsxRepository: prisma/web
Length of output: 3056
🏁 Script executed:
# Read the switch.tsx file to verify its content
cat packages/eclipse/src/components/switch.tsxRepository: prisma/web
Length of output: 1520
🏁 Script executed:
# Search for any usage of Switch from radix-ui to understand if this is a typo
rg 'from.*radix-ui' packages/eclipse/src/components/ | grep -v '@radix-ui'Repository: prisma/web
Length of output: 150
🏁 Script executed:
# Search for any file that might be exporting from radix-ui (barrel export)
rg 'export.*from.*@radix-ui' packages/eclipse/src/ | head -20Repository: prisma/web
Length of output: 36
🏁 Script executed:
# Check if there's an index or barrel file in node_modules or package.json that exports radix-ui
rg 'radix-ui' packages/eclipse/ -g '*.json' -g '*.ts' -g '*.tsx' | grep -i 'package\|export\|from.*radix'Repository: prisma/web
Length of output: 2663
🏁 Script executed:
# Check the actual Switch component usage - is SwitchPrimitive.Root a valid export from "radix-ui"?
rg 'SwitchPrimitive\.Root' packages/eclipse/src/Repository: prisma/web
Length of output: 293
Add "use client" directive and fix the Radix Switch import path.
This component uses Radix Switch primitives, which are client-only. The missing "use client" directive will cause Next.js import errors when consumed from React Server Components or MDX. Additionally, the import from "radix-ui" is non-standard—all other Radix components in the codebase use scoped imports (e.g., @radix-ui/react-checkbox). The Switch component should import from @radix-ui/react-switch to match the established pattern and ensure correct module resolution.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/eclipse/src/components/switch.tsx` around lines 1 - 4, Add the
client directive and correct Radix import: this file uses the Radix Switch
primitive so add "use client" as the first line of
packages/eclipse/src/components/switch.tsx, and change the import from
"radix-ui" to the scoped package "@radix-ui/react-switch" (the existing import
alias SwitchPrimitive should be preserved), ensuring the Switch component and
any references to SwitchPrimitive continue to work with the updated import.
| @@ -0,0 +1,33 @@ | |||
| import * as React from "react"; | |||
| import { Switch as SwitchPrimitive } from "radix-ui"; | |||
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, let's check the actual file and its imports
cat -n packages/eclipse/src/components/switch.tsx | head -20Repository: prisma/web
Length of output: 1180
🏁 Script executed:
# Check the package.json to understand dependencies
cat packages/eclipse/package.jsonRepository: prisma/web
Length of output: 1739
🏁 Script executed:
# Search for other radix-ui imports in the project to understand the pattern
rg "from.*radix-ui" packages/eclipse/src/ -A 1Repository: prisma/web
Length of output: 2488
🌐 Web query:
radix-ui npm package exports what components
💡 Result:
The radix-ui package’s main entry (import { … } from "radix-ui") re-exports these component namespaces (each is the * as namespace from the corresponding @radix-ui/react-* package) [1]:
AccessibleIconAccordionAlertDialogAspectRatioAvatarCheckboxCollapsibleContextMenuDialogDirectionDropdownMenuFormHoverCardLabelMenubarNavigationMenuPopoverPortalProgressRadioGroupScrollAreaSelectSeparatorSliderSlotSwitchTabsToastToggleToggleGroupToolbarTooltipVisuallyHiddenunstable_OneTimePasswordFieldunstable_PasswordToggleField[1]
Example usage (from the Radix docs): import { Dialog } from "radix-ui"; [2]
Sources: [1] [2]
🌐 Web query:
@radix-ui/react-switch npm package Switch.Root Switch.Thumb
💡 Result:
@radix-ui/react-switch exports an accessible, unstyled Switch primitive composed of two main parts:
Switch.Root: the interactive switch “button” (holds state, focus/keyboard behavior, form integration). It exposes props likechecked,defaultChecked,onCheckedChange,disabled,required,name,value, and data attributes likedata-state="checked|unchecked". [1]Switch.Thumb: the visual thumb/knob inside the root; it also receivesdata-state/data-disabledfor styling. [1]
Install
npm i `@radix-ui/react-switch`[2]
Basic usage
import * as Switch from "@radix-ui/react-switch";
export function MySwitch() {
return (
<Switch.Root className="SwitchRoot" id="airplane-mode">
<Switch.Thumb className="SwitchThumb" />
</Switch.Root>
);
}[1]
Controlled usage
import * as Switch from "@radix-ui/react-switch";
import * as React from "react";
export function Controlled() {
const [checked, setChecked] = React.useState(false);
return (
<Switch.Root checked={checked} onCheckedChange={setChecked}>
<Switch.Thumb />
</Switch.Root>
);
}[1]
Sources: Radix Switch docs [1], npm package page [2].
Use the scoped @radix-ui/react-switch package for consistency with the rest of the codebase.
The radix-ui aggregator package does re-export Switch, so the current import works. However, every other component in this project (tooltip, dialog, checkbox, separator, etc.) imports from the scoped @radix-ui/react-* packages. For consistency and clarity, add @radix-ui/react-switch to dependencies and update the import pattern:
Recommended change
-import { Switch as SwitchPrimitive } from "radix-ui";
+import * as SwitchPrimitive from "@radix-ui/react-switch";🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/eclipse/src/components/switch.tsx` at line 2, Replace the import of
SwitchPrimitive from the aggregator "radix-ui" with the scoped package
"@radix-ui/react-switch" and add "@radix-ui/react-switch" to package.json
dependencies; specifically update the import statement that currently reads like
`import { Switch as SwitchPrimitive } from "radix-ui";` to import from
"@radix-ui/react-switch" and run your package install so SwitchPrimitive
resolves the same way as other components (tooltip/dialog/checkbox) in the
codebase.
| <SwitchPrimitive.Root | ||
| data-slot="switch" | ||
| data-size={size} | ||
| className={cn( | ||
| "peer data-[state=checked]:bg-background-neutral-reverse data-[state=unchecked]:bg-background-neutral-strong focus-visible:border-ring group/switch inline-flex shrink-0 items-center rounded-circle border-1 border-transparent shadow-xs transition-all outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed data-[size=default]:h-[1.15rem] data-[size=default]:w-8 disabled:outline-stroke-neutral-weak disabled:outline disabled:outline-solid disabled:bg-background-neutral-weak disabled:[&>span]:bg-foreground-neutral-weaker [&>span]:bg-foreground-neutral-reverse", | ||
| className, | ||
| )} | ||
| {...props} | ||
| > | ||
| <SwitchPrimitive.Thumb | ||
| data-slot="switch-thumb" | ||
| className={cn( | ||
| "dark:data-[state=checked]:bg-primary-foreground pointer-events-none block rounded-full ring-0 transition-transform group-data-[size=default]/switch:size-3 data-[state=checked]:translate-x-[calc(100%+3px)] data-[state=unchecked]:translate-x-[2px] disabled:bg-foreground-neutral-weaker", | ||
| )} |
There was a problem hiding this comment.
size="sm" currently has no dimensions.
Only data-[size=default] is styled, so the small variant renders without width/height and the thumb has no size. Add data-[size=sm] sizing for both root and thumb (and adjust translations if needed).
🧩 Example sizing additions for the sm variant
className={cn(
- "peer data-[state=checked]:bg-background-neutral-reverse data-[state=unchecked]:bg-background-neutral-strong focus-visible:border-ring group/switch inline-flex shrink-0 items-center rounded-circle border-1 border-transparent shadow-xs transition-all outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed data-[size=default]:h-[1.15rem] data-[size=default]:w-8 disabled:outline-stroke-neutral-weak disabled:outline disabled:outline-solid disabled:bg-background-neutral-weak disabled:[&>span]:bg-foreground-neutral-weaker [&>span]:bg-foreground-neutral-reverse",
+ "peer data-[state=checked]:bg-background-neutral-reverse data-[state=unchecked]:bg-background-neutral-strong focus-visible:border-ring group/switch inline-flex shrink-0 items-center rounded-circle border-1 border-transparent shadow-xs transition-all outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed data-[size=default]:h-[1.15rem] data-[size=default]:w-8 data-[size=sm]:h-3.5 data-[size=sm]:w-6 disabled:outline-stroke-neutral-weak disabled:outline disabled:outline-solid disabled:bg-background-neutral-weak disabled:[&>span]:bg-foreground-neutral-weaker [&>span]:bg-foreground-neutral-reverse",
className,
)}
@@
<SwitchPrimitive.Thumb
data-slot="switch-thumb"
className={cn(
- "dark:data-[state=checked]:bg-primary-foreground pointer-events-none block rounded-full ring-0 transition-transform group-data-[size=default]/switch:size-3 data-[state=checked]:translate-x-[calc(100%+3px)] data-[state=unchecked]:translate-x-[2px] disabled:bg-foreground-neutral-weaker",
+ "dark:data-[state=checked]:bg-primary-foreground pointer-events-none block rounded-full ring-0 transition-transform group-data-[size=default]/switch:size-3 group-data-[size=sm]/switch:size-2.5 data-[state=checked]:translate-x-[calc(100%+3px)] data-[state=unchecked]:translate-x-[2px] disabled:bg-foreground-neutral-weaker",
)}
/>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <SwitchPrimitive.Root | |
| data-slot="switch" | |
| data-size={size} | |
| className={cn( | |
| "peer data-[state=checked]:bg-background-neutral-reverse data-[state=unchecked]:bg-background-neutral-strong focus-visible:border-ring group/switch inline-flex shrink-0 items-center rounded-circle border-1 border-transparent shadow-xs transition-all outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed data-[size=default]:h-[1.15rem] data-[size=default]:w-8 disabled:outline-stroke-neutral-weak disabled:outline disabled:outline-solid disabled:bg-background-neutral-weak disabled:[&>span]:bg-foreground-neutral-weaker [&>span]:bg-foreground-neutral-reverse", | |
| className, | |
| )} | |
| {...props} | |
| > | |
| <SwitchPrimitive.Thumb | |
| data-slot="switch-thumb" | |
| className={cn( | |
| "dark:data-[state=checked]:bg-primary-foreground pointer-events-none block rounded-full ring-0 transition-transform group-data-[size=default]/switch:size-3 data-[state=checked]:translate-x-[calc(100%+3px)] data-[state=unchecked]:translate-x-[2px] disabled:bg-foreground-neutral-weaker", | |
| )} | |
| <SwitchPrimitive.Root | |
| data-slot="switch" | |
| data-size={size} | |
| className={cn( | |
| "peer data-[state=checked]:bg-background-neutral-reverse data-[state=unchecked]:bg-background-neutral-strong focus-visible:border-ring group/switch inline-flex shrink-0 items-center rounded-circle border-1 border-transparent shadow-xs transition-all outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed data-[size=default]:h-[1.15rem] data-[size=default]:w-8 data-[size=sm]:h-3.5 data-[size=sm]:w-6 disabled:outline-stroke-neutral-weak disabled:outline disabled:outline-solid disabled:bg-background-neutral-weak disabled:[&>span]:bg-foreground-neutral-weaker [&>span]:bg-foreground-neutral-reverse", | |
| className, | |
| )} | |
| {...props} | |
| > | |
| <SwitchPrimitive.Thumb | |
| data-slot="switch-thumb" | |
| className={cn( | |
| "dark:data-[state=checked]:bg-primary-foreground pointer-events-none block rounded-full ring-0 transition-transform group-data-[size=default]/switch:size-3 group-data-[size=sm]/switch:size-2.5 data-[state=checked]:translate-x-[calc(100%+3px)] data-[state=unchecked]:translate-x-[2px] disabled:bg-foreground-neutral-weaker", | |
| )} |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/eclipse/src/components/switch.tsx` around lines 14 - 27, The small
variant lacks size classes so SwitchPrimitive.Root and SwitchPrimitive.Thumb
render without dimensions; add matching data-[size=sm] rules alongside the
existing data-[size=default] ones: on SwitchPrimitive.Root add
data-[size=sm]:h-... and data-[size=sm]:w-... (and any disabled/outline
equivalents) and on SwitchPrimitive.Thumb add data-[size=sm] sizing
(width/height) and adjust the translate-x for data-[state=checked] for the sm
thumb to correctly move to the end; update the cn calls where
data-[size=default] appears to include the corresponding data-[size=sm] tokens
so the small variant gets proper root and thumb dimensions and translations.
Summary by CodeRabbit
Release Notes
New Features
Chores